﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VAdvantage.Model;
using VAdvantage.Logging;
using VAdvantage.Utility;
using System.Data;
using VAdvantage.DataBase;
using VAdvantage.Framework;
using VAdvantage.Classes;
using System.Data.SqlClient;
using System.Windows.Data;
using VAdvantage.Process;
using System.Text;

namespace VAdvantage.Apps.AForms
{
    public partial class VPaySelect : UserControl, FormPanel
    {
        #region Private Variable
        private int _C_PaySelection_ID = 0;
        VAdvantage.Grids.MyDataGridCheckBoxColumn chk = new VAdvantage.Grids.MyDataGridCheckBoxColumn();
        private string ISOCode = "";
        private static long serialVersionUID = 1L;
        private int C_Currency_ID = 0;
        /**	Window No			*/
        private int m_WindowNo = 0;
        /**	FormFrame			*/
        private FormFrame m_frame;
        /** Format                  */
        // private DecimalFormat   m_format = DisplayType.getNumberFormat(DisplayTypeConstants.Amount);
        /** Bank Balance            */
        private Decimal m_bankBalance = new Decimal(0.0);
        /** SQL for Query           */
        private String m_sql;
        /** Number of selected rows */
        private int m_noSelected = 0;
        /** Client ID               */
        private int m_AD_Client_ID = 0;
        /**/
        private bool m_isLocked = false;
        /** Payment Selection		*/
        private MPaySelection m_ps = null;
        /**	Logger			*/
        private static VLogger log = VLogger.GetVLogger(typeof(VPaySelect).FullName);
        Boolean bAcc = false;
        #endregion

        /// <summary>
        /// default constructor
        /// </summary>
        public VPaySelect()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Initialize Panel
        /// </summary>
        /// <param name="WindowNo"></param>
        /// <param name="frame"></param>
        public void Init(int WindowNo, FormFrame frame)
        {

            log.Info("");
            m_WindowNo = WindowNo;
            m_frame = frame;
            try
            {
                JbInit();
                FillCombos();
                DynInit();
                chk.Click += new RoutedEventHandler(chk_Click);
                this.Visibility = System.Windows.Visibility.Visible;
                m_frame.ContentGrid.Children.Add(this);
                m_frame.Focus();
                txtPaymentAmount.Text = "0";
                m_frame.SetTitle(Msg.GetMsg(Envs.GetCtx(), "PaymentSelection(Manual)"));
                btnGenerate.IsEnabled = false;
                vdtpPayDate.SelectedDate = System.DateTime.Now;
                vDataStatus.Content = "0 " + Msg.GetMsg(Envs.GetCtx(), "Selected") + " - 0.00, " + Msg.GetMsg(Envs.GetCtx(), "Remaining") + " 0.00";
                SetBusy(false);
            }
            catch (Exception e)
            {
                log.Log(Level.SEVERE, "", e);
            }

        }

        /// <summary>
        /// Dispose
        /// </summary>
        public void Dispose()
        {
            if (m_frame != null)
            {
                m_frame.Dispose();
            }
            m_frame = null;
        }

        void chk_Click(object sender, RoutedEventArgs e)
        {
            int rowsSelected = 0;
            Decimal? totalAmt = 0;
            BindingSource rowSource = vdgvPayment.ItemsSource as BindingSource;
            if (vdgvPayment.CurrentColumn.DisplayIndex == 0 && vdgvPayment.SelectedIndex > -1)
            {
                if (rowSource.Count != 0)
                {
                    Boolean isPressed = Convert.ToBoolean(((BindableObject)rowSource[0]).GetValue("SELECTROW"));
                    bool equals = true;
                    for (int i = 0; i < rowSource.Count; i++)
                    {
                        equals = isPressed.Equals(Convert.ToBoolean(((BindableObject)rowSource[i]).GetValue("SELECTROW")));
                        if (vdgvPayment.SelectedIndex == i && vdgvPayment.CurrentColumn.DisplayIndex == 0)
                        {
                            if (Convert.ToBoolean(((BindableObject)rowSource[i]).GetValue("SELECTROW")))
                            {
                                ((BindableObject)vdgvPayment.SelectedItem).SetValue("SELECTROW", "false");
                                ((BindableObject)rowSource[i]).SetValue("SELECTROW", "false");
                            }
                            else
                            {
                                ((BindableObject)vdgvPayment.SelectedItem).SetValue("SELECTROW", "true");
                                ((BindableObject)rowSource[i]).SetValue("SELECTROW", "true");
                            }
                        }

                        if ((Convert.ToBoolean(((BindableObject)rowSource[i]).GetValue("SELECTROW"))))
                        {
                            Decimal? amt = Util.GetValueOfDecimal(((BindableObject)rowSource[i]).GetValue("PAYMENTAMOUNT"));
                            totalAmt = Decimal.Add(amt.Value, totalAmt.Value);
                            rowsSelected++;
                        }
                    }
                }
                if (rowsSelected > 0)
                {
                    Decimal? remaining = Decimal.Subtract(m_bankBalance, totalAmt.Value);
                    vDataStatus.Content = rowsSelected + " " + Msg.GetMsg(Envs.GetCtx(), "Selected") + " - " + totalAmt.Value.ToString() + ", " + Msg.GetMsg(Envs.GetCtx(), "Remaining") + " " + remaining.Value.ToString();
                    txtPaymentAmount.Text = totalAmt.Value.ToString();
                    btnGenerate.IsEnabled = true;
                }
                else
                {
                    vDataStatus.Content = "0 " + Msg.GetMsg(Envs.GetCtx(), "Selected") + " - 0.00, " + Msg.GetMsg(Envs.GetCtx(), "Remaining") + " 0.00";
                    btnGenerate.IsEnabled = false;
                }
            }
        }

        private void FillCombos()
        {
            string sqlBankAccount = "SELECT ba.C_BankAccount_ID,"                       //  1
                 + "b.Name || ' ' || ba.AccountNo AS Name, "          //  2
                   + "ba.C_Currency_ID, c.ISO_Code,"                   //  3..4
                   + "ba.CurrentBalance "                              //  5
                 + "FROM C_Bank b "
                 + "INNER JOIN C_BankAccount ba ON (b.C_Bank_ID=ba.C_Bank_ID) "
                 + "INNER JOIN C_Currency c ON (ba.C_Currency_ID=c.C_Currency_ID) "
                 + " AND ba.IsActive = 'Y'"
                 + " AND EXISTS (SELECT * FROM C_BankAccountDoc d WHERE d.C_BankAccount_ID=ba.C_BankAccount_ID) "
                 + " AND (ba.AD_Org_ID IN (SELECT ro.AD_Org_ID FROM AD_Role_OrgAccess ro"
                 + " WHERE ro.AD_Role_ID = " + Envs.GetCtx().GetAD_Role_ID() + " AND ro.IsActive = 'Y')"
                 + " OR (ba.AD_Org_ID = 0 AND EXISTS (SELECT ro.AD_Org_ID FROM AD_Role_OrgAccess ro"
                 + " WHERE ro.AD_Role_ID = " + Envs.GetCtx().GetAD_Role_ID() + " AND ro.IsActive = 'Y')) "
                 + " OR EXISTS (SELECT NULL FROM AD_Role WHERE AD_Role_ID=" + Envs.GetCtx().GetAD_Role_ID() + " AND IsAccessAllOrgs='Y'))"
                 + " AND ba.ad_org_id = " + Envs.GetCtx().GetAD_Org_ID()
                 + " ORDER BY 2";

            string sqlBPartner = "select bp.C_BPartner_ID, bp.Name from c_bpartner bp where exists (SELECT * FROM C_Invoice i WHERE "
            + " bp.C_BPartner_ID=i.C_BPartner_ID AND (i.IsSOTrx='N' OR (i.IsSOTrx='Y' AND i.PaymentRule='D'))AND i.IsPaid <>'Y') and bp.AD_Client_ID IN (0, " + Envs.GetCtx().GetAD_Client_ID() + ") AND (COALESCE(bp.AD_Org_ID,0) IN(0," + Envs.GetCtx().GetAD_Org_ID() + ")) ORDER BY 2";

            DataSet dsBankAccount = null;
            DataSet dsBPartner = null;

            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                dsBankAccount = DB.ExecuteDataset(sqlBankAccount, null, null);
                dsBPartner = DB.ExecuteDataset(sqlBPartner, null, null);
                Dispatcher.BeginInvoke(delegate
                {
                    if (dsBankAccount.Tables[0].Rows.Count == 0)
                    {
                        log.SaveError("NoBankAccount", "NoBankAccount");
                    }
                    else
                    {
                        ISOCode = Util.GetValueOfString(dsBankAccount.Tables[0].Rows[0]["ISO_Code"]);
                        lblCurency.Content = ISOCode;

                        m_bankBalance = Util.GetValueOfDecimal(dsBankAccount.Tables[0].Rows[0]["CurrentBalance"]);

                        cmbBankAccount.ItemsSource = dsBankAccount.Tables[0].GetBindableData(new Connector());
                        cmbBankAccount.SelectedValuePath = "C_BANKACCOUNT_ID";
                        cmbBankAccount.DisplayMemberPath = "NAME";
                        cmbBankAccount.SelectedIndex = 0;

                        cmbBPartner.ItemsSource = dsBPartner.Tables[0].GetBindableData(new Connector());
                        cmbBPartner.SelectedValuePath = "C_BPARTNER_ID";
                        cmbBPartner.DisplayMemberPath = "NAME";

                        C_Currency_ID = Util.GetValueOfInt(dsBankAccount.Tables[0].Rows[0]["C_Currency_ID"]);

                        int C_BankAccount_ID = Util.GetValueOfInt(cmbBankAccount.SelectedValue);

                        lblCurrentBalanceAmt.Content = Util.GetValueOfDecimal(m_bankBalance);

                        string sqlPaymentRule = "select Name, Value from ad_ref_list where ad_reference_id = 195 "
                      + " AND AD_Ref_List.Value IN (SELECT PaymentRule FROM C_BankAccountDoc WHERE C_BankAccount_ID=" + C_BankAccount_ID + ") ORDER BY 2";

                        DataSet dsPaymentRule = null;
                        System.Threading.ThreadPool.QueueUserWorkItem(delegate
                        {
                            dsPaymentRule = DB.ExecuteDataset(sqlPaymentRule, null, null);

                            Dispatcher.BeginInvoke(delegate
                            {
                                cmbPaymentRule.ItemsSource = dsPaymentRule.Tables[0].GetBindableData(new Connector());
                                cmbPaymentRule.SelectedValuePath = "VALUE";
                                cmbPaymentRule.DisplayMemberPath = "NAME";
                                if (dsPaymentRule.Tables[0].Rows.Count > 0)
                                {
                                    cmbPaymentRule.SelectedIndex = 0;
                                }
                                bAcc = true;
                            });
                        });
                    }
                });

            });
        }

        private List<ValueNamePair> ReturnKeyname(DataTable dtv)
        {
            List<ValueNamePair> _data = new List<ValueNamePair>();
            for (int i = 0; i < dtv.Rows.Count; i++)
            {
                _data.Add(new ValueNamePair(dtv.Rows[i][0].ToString(), dtv.Rows[i][1].ToString()));
            }
            return _data;
        }

        private void JbInit()
        {
            lblBankAccount.Content = Msg.Translate(Envs.GetCtx(), "C_BankAccount_ID");
            lblBPartner.Content = Msg.Translate(Envs.GetCtx(), "C_BPartner_ID");
            lblPayDate.Content = Msg.Translate(Envs.GetCtx(), "PayDate");
            lblPaymentRule.Content = Msg.Translate(Envs.GetCtx(), "PaymentRule");
            lblCurrentBalance.Content = Msg.Translate(Envs.GetCtx(), "CurrentBalance");
            lblCurrentBalanceAmt.Content = "0";
            chkDue.Content = Msg.GetMsg(Envs.GetCtx(), "OnlyDue");
            // chkDue.Checked += new RoutedEventHandler(chkDue_Checked);
            chkDue.Click += new RoutedEventHandler(chkDue_Click);
        }

        /// <summary>
        ///  Dynamic Init.
        ///    - Load Bank Info
        ///      - Load BPartner
        ///        - Init Table
        /// </summary>
        private void DynInit()
        {
            Ctx ctx = Envs.GetCtx();
            GridColumns();
            m_AD_Client_ID = Envs.GetCtx().GetAD_Client_ID();

            // m_sql = "SELECT 'false' as SELECTROW, i.C_INVOICE_ID, i.DateInvoiced+p.NetDays AS DUEDATE, bp.NAME as BUSINESSPARTNER,i.C_BPARTNER_ID, i.DOCUMENTNO, c.ISO_CODE as CURRENCY,i.C_CURRENCY_ID, i.GRANDTOTAL, "
            //+ " paymentTermDiscount(i.GrandTotal,i.C_Currency_ID,i.C_PaymentTerm_ID,i.DateInvoiced, @param1) as DISCOUNTAMOUNT, SysDate-paymentTermDueDays(i.C_PaymentTerm_ID,i.DateInvoiced,SysDate) as DISCOUNTDATE, "
            //+ " currencyConvert(invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID),i.C_Currency_ID, @param2, @param3,i.C_ConversionType_ID, i.AD_Client_ID,i.AD_Org_ID) as AMOUNTDUE, "
            //+ " currencyConvert(invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID)-paymentTermDiscount(i.GrandTotal,i.C_Currency_ID,i.C_PaymentTerm_ID,i.DateInvoiced, @param4)  , "
            //+ " i.C_Currency_ID, @param5, @param6,i.C_ConversionType_ID, i.AD_Client_ID,i.AD_Org_ID) as PAYMENTAMOUNT FROM C_Invoice_v i INNER JOIN C_BPartner bp ON "
            //+ " (i.C_BPartner_ID=bp.C_BPartner_ID) INNER JOIN C_Currency c ON (i.C_Currency_ID=c.C_Currency_ID) INNER JOIN C_PaymentTerm p ON "
            //+ " (i.C_PaymentTerm_ID=p.C_PaymentTerm_ID) WHERE i.IsSOTrx= @param7 AND IsPaid='N' AND NOT EXISTS (SELECT * FROM C_PaySelectionLine psl "
            //+ " WHERE i.C_Invoice_ID=psl.C_Invoice_ID AND psl.C_PaySelectionCheck_ID IS NOT NULL AND COALESCE(psl.IsCancelled,'N') = 'N') AND "
            //+ " i.DocStatus IN ('CO','CL') AND i.AD_Client_ID= @param8 AND i.AD_Client_ID IN(0," + m_AD_Client_ID + ") AND (COALESCE(i.AD_Org_ID,0) IN(0," + Envs.GetCtx().GetAD_Org_ID() + "))";

            m_sql = "SELECT 'false' as SELECTROW, i.C_INVOICE_ID, i.DateInvoiced+p.NetDays AS DUEDATE, bp.NAME as BUSINESSPARTNER,i.C_BPARTNER_ID, i.DOCUMENTNO, c.ISO_CODE as CURRENCY,i.C_CURRENCY_ID, i.GRANDTOTAL, "
         + " paymentTermDiscount(i.GrandTotal,i.C_Currency_ID,i.C_PaymentTerm_ID,i.DateInvoiced, @param1) as DISCOUNTAMOUNT, SysDate-paymentTermDueDays(i.C_PaymentTerm_ID,i.DateInvoiced,SysDate) as DISCOUNTDATE, "
         + " currencyConvert(invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID),i.C_Currency_ID, @param2, @param3,i.C_ConversionType_ID, i.AD_Client_ID,i.AD_Org_ID) as AMOUNTDUE, "
         + " currencyConvert(invoiceOpen(i.C_Invoice_ID,i.C_InvoicePaySchedule_ID)-paymentTermDiscount(i.GrandTotal,i.C_Currency_ID,i.C_PaymentTerm_ID,i.DateInvoiced, @param4)  , "
         + " i.C_Currency_ID, @param5, @param6,i.C_ConversionType_ID, i.AD_Client_ID,i.AD_Org_ID) as PAYMENTAMOUNT FROM C_Invoice_v i INNER JOIN C_BPartner bp ON "
         + " (i.C_BPartner_ID=bp.C_BPartner_ID) INNER JOIN C_Currency c ON (i.C_Currency_ID=c.C_Currency_ID) INNER JOIN C_PaymentTerm p ON "
         + " (i.C_PaymentTerm_ID=p.C_PaymentTerm_ID) WHERE i.IsSOTrx= @param7 AND IsPaid='N' AND "
         + " i.DocStatus IN ('CO','CL') AND i.AD_Client_ID= @param8 AND i.AD_Client_ID IN(0," + m_AD_Client_ID + ") AND (COALESCE(i.AD_Org_ID,0) IN(0," + Envs.GetCtx().GetAD_Org_ID() + "))";
        }

        private void EventHandling()
        {
            btnRefresh.Click += new RoutedEventHandler(btnRefresh_Click);
            btnGenerate.Click += new RoutedEventHandler(btnGenerate_Click);
            //chkDue.Click += new RoutedEventHandler(chkDue_Click);
        }

        void chkDue_Click(object sender, RoutedEventArgs e)
        {
            if (cmbBPartner.SelectedIndex == -1)
            {
                ShowMessage.Info("SelectBusinessPartnerFirst", true, null, null);
                return;
            }
            int countParam = 8;
            log.Config("");
            //  not yet initialized
            if (m_sql == null)
            {
                return;
            }

            String sql = m_sql;
            DateTime payDate = (DateTime)vdtpPayDate.SelectedDate;
            string paymentDate = payDate.ToString("dd-MMM-yyyy");
            int C_BankAccount_ID = Util.GetValueOfInt(cmbBankAccount.SelectedValue);
            log.Config("PayDate=" + payDate);
            String isSOTrx = "N";
            string paymentRule = Util.GetValueOfString(cmbPaymentRule.SelectedValue);
            if (paymentRule != "" && X_C_Order.PAYMENTRULE_DirectDebit.Equals(paymentRule))
            {
                isSOTrx = "Y";
                sql += " AND i.PaymentRule='" + X_C_Order.PAYMENTRULE_DirectDebit + "'";
            }
            if ((bool)chkDue.IsChecked)
            {
                sql += " AND i.DateInvoiced+p.NetDays <= @param9";
                countParam++;
            }
            int C_BPartner_ID = Util.GetValueOfInt(cmbBPartner.SelectedValue);
            if (C_BPartner_ID != 0)
            {
                sql += " AND i.C_BPartner_ID=@param10";
                countParam++;
            }
            sql += " ORDER BY 2,3";
            log.Finest(sql + " - C_Currecny_ID=" + C_Currency_ID + ", C_BPartner_ID=" + C_BPartner_ID);
            ////  Get Open Invoices
            SqlParameter[] para = null;
            try
            {
                para = new SqlParameter[countParam];
                int index = 0;
                para[index++] = new SqlParameter("@param1", paymentDate);
                para[index++] = new SqlParameter("@param2", C_Currency_ID);
                para[index++] = new SqlParameter("@param3", paymentDate);
                para[index++] = new SqlParameter("@param4", paymentDate);
                para[index++] = new SqlParameter("@param5", C_Currency_ID);
                para[index++] = new SqlParameter("@param6", paymentDate);
                para[index++] = new SqlParameter("@param7", isSOTrx);
                para[index++] = new SqlParameter("@param8", m_AD_Client_ID);

                if ((bool)chkDue.IsChecked)
                {
                    para[index++] = new SqlParameter("@param9", paymentDate);
                }
                if (C_BPartner_ID != 0)
                {
                    para[index++] = new SqlParameter("@param10", C_BPartner_ID);
                }

                System.Threading.ThreadPool.QueueUserWorkItem(delegate
                {
                    DataSet ds = DB.ExecuteDataset(sql, para, null);

                    Dispatcher.BeginInvoke(delegate
                    {
                        if (ds != null)
                        {
                            BindingSource source = new BindingSource(ds.Tables[0].GetBindableData(new Connector()));
                            vdgvPayment.ItemsSource = source;
                        }
                        btnGenerate.IsEnabled = false;
                        SetBusy(false);
                    });
                });

            }
            catch
            {
                log.Log(Level.SEVERE, sql, null);
            }
        }

        void chkDue_Checked(object sender, RoutedEventArgs e)
        {
            int countParam = 8;
            log.Config("");
            //  not yet initialized
            if (m_sql == null)
            {
                return;
            }

            String sql = m_sql;
            DateTime payDate = (DateTime)vdtpPayDate.SelectedDate;
            string paymentDate = payDate.ToString("dd-MMM-yyyy");
            int C_BankAccount_ID = Util.GetValueOfInt(cmbBankAccount.SelectedValue);
            log.Config("PayDate=" + payDate);
            String isSOTrx = "N";
            string paymentRule = Util.GetValueOfString(cmbPaymentRule.SelectedValue);
            if (paymentRule != "" && X_C_Order.PAYMENTRULE_DirectDebit.Equals(paymentRule))
            {
                isSOTrx = "Y";
                sql += " AND i.PaymentRule='" + X_C_Order.PAYMENTRULE_DirectDebit + "'";
            }
            if ((bool)chkDue.IsChecked)
            {
                sql += " AND i.DateInvoiced+p.NetDays <= @param9";
                countParam++;
            }
            int C_BPartner_ID = Util.GetValueOfInt(cmbBPartner.SelectedValue);
            if (C_BPartner_ID != 0)
            {
                sql += " AND i.C_BPartner_ID=@param10";
                countParam++;
            }
            sql += " ORDER BY 2,3";
            log.Finest(sql + " - C_Currecny_ID=" + C_Currency_ID + ", C_BPartner_ID=" + C_BPartner_ID);
            ////  Get Open Invoices
            SqlParameter[] para = null;
            try
            {
                para = new SqlParameter[countParam];
                int index = 0;
                para[index++] = new SqlParameter("@param1", paymentDate);
                para[index++] = new SqlParameter("@param2", C_Currency_ID);
                para[index++] = new SqlParameter("@param3", paymentDate);
                para[index++] = new SqlParameter("@param4", paymentDate);
                para[index++] = new SqlParameter("@param5", C_Currency_ID);
                para[index++] = new SqlParameter("@param6", paymentDate);
                para[index++] = new SqlParameter("@param7", isSOTrx);
                para[index++] = new SqlParameter("@param8", m_AD_Client_ID);

                if ((bool)chkDue.IsChecked)
                {
                    para[index++] = new SqlParameter("@param9", paymentDate);
                }
                if (C_BPartner_ID != 0)
                {
                    para[index++] = new SqlParameter("@param10", C_BPartner_ID);
                }

                System.Threading.ThreadPool.QueueUserWorkItem(delegate
                {
                    DataSet ds = DB.ExecuteDataset(sql, para, null);

                    Dispatcher.BeginInvoke(delegate
                    {
                        if (ds != null)
                        {
                            BindingSource source = new BindingSource(ds.Tables[0].GetBindableData(new Connector()));
                            vdgvPayment.ItemsSource = source;
                        }
                        btnGenerate.IsEnabled = false;
                        SetBusy(false);
                    });
                });

            }
            catch
            {
                log.Log(Level.SEVERE, sql, null);
            }
        }

        private void GridColumns()
        {
            chk.Header = Msg.GetMsg(Envs.GetCtx(), "SELECT");
            chk.Binding = new System.Windows.Data.Binding("SELECTROW");
            chk.DataPropertyName = "SELECTROW";
            chk.DataGrid = vdgvPayment;
            chk.IsThreeState = false;
            chk.IsReadOnly = false;
            vdgvPayment.Columns.Add(chk);

            DataGridTextColumn invID = new DataGridTextColumn();
            invID.Header = Msg.GetMsg(Envs.GetContext(), "C_INVOICE_ID");
            invID.Binding = new System.Windows.Data.Binding("C_INVOICE_ID");
            invID.IsReadOnly = true;
            invID.Visibility = Visibility.Collapsed;
            vdgvPayment.Columns.Add(invID);

            DataGridTextColumn dueDate = new DataGridTextColumn();
            dueDate.Header = Msg.GetMsg(Envs.GetContext(), "DUEDATE");
            dueDate.Binding = new System.Windows.Data.Binding("DUEDATE");
            dueDate.IsReadOnly = true;
            dueDate.Visibility = Visibility.Visible;
            vdgvPayment.Columns.Add(dueDate);

            DataGridTextColumn bp = new DataGridTextColumn();
            bp.Header = Msg.GetMsg(Envs.GetContext(), "BUSINESSPARTNER");
            bp.Binding = new System.Windows.Data.Binding("BUSINESSPARTNER");
            bp.IsReadOnly = true;
            bp.Visibility = Visibility.Visible;
            vdgvPayment.Columns.Add(bp);

            DataGridTextColumn docNO = new DataGridTextColumn();
            docNO.Header = Msg.GetMsg(Envs.GetContext(), "DOCUMENTNO");
            docNO.Binding = new System.Windows.Data.Binding("DOCUMENTNO");
            docNO.IsReadOnly = true;
            docNO.Visibility = Visibility.Visible;
            vdgvPayment.Columns.Add(docNO);


            DataGridTextColumn curr = new DataGridTextColumn();
            curr.Header = Msg.GetMsg(Envs.GetContext(), "CURRENCY");
            curr.Binding = new System.Windows.Data.Binding("CURRENCY");
            curr.IsReadOnly = true;
            curr.Visibility = Visibility.Visible;
            vdgvPayment.Columns.Add(curr);

            DataGridTextColumn gTot = new DataGridTextColumn();
            gTot.Header = Msg.GetMsg(Envs.GetContext(), "GRANDTOTAL");
            gTot.Binding = new System.Windows.Data.Binding("GRANDTOTAL");
            gTot.IsReadOnly = true;
            gTot.Visibility = Visibility.Visible;

            vdgvPayment.Columns.Add(gTot);

            DataGridTextColumn disAmt = new DataGridTextColumn();
            disAmt.Header = Msg.GetMsg(Envs.GetContext(), "DISCOUNTAMOUNT");
            disAmt.Binding = new System.Windows.Data.Binding("DISCOUNTAMOUNT");
            disAmt.IsReadOnly = true;
            disAmt.Visibility = Visibility.Visible;
            vdgvPayment.Columns.Add(disAmt);

            DataGridTextColumn disDate = new DataGridTextColumn();
            disDate.Header = Msg.GetMsg(Envs.GetContext(), "DISCOUNTDATE");
            disDate.Binding = new System.Windows.Data.Binding("DISCOUNTDATE");
            disDate.IsReadOnly = true;
            disDate.Visibility = Visibility.Visible;
            vdgvPayment.Columns.Add(disDate);

            DataGridTextColumn amtDue = new DataGridTextColumn();
            amtDue.Header = Msg.GetMsg(Envs.GetContext(), "AMOUNTDUE");
            amtDue.Binding = new System.Windows.Data.Binding("AMOUNTDUE");
            amtDue.IsReadOnly = true;
            amtDue.Visibility = Visibility.Visible;
            vdgvPayment.Columns.Add(amtDue);

            DataGridTextColumn pmtAmt = new DataGridTextColumn();
            pmtAmt.Header = Msg.GetMsg(Envs.GetContext(), "PAYMENTAMOUNT");
            pmtAmt.Binding = new System.Windows.Data.Binding("PAYMENTAMOUNT");
            pmtAmt.IsReadOnly = true;
            pmtAmt.Visibility = Visibility.Visible;
            vdgvPayment.Columns.Add(pmtAmt);

            vdgvPayment.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible;
        }

        /// <summary>
        /// Load Bank Info - Load Info from Bank Account and valid Documents (PaymentRule)
        /// </summary>
        private void LoadBankInfo()
        {

            string sqlBankAccount = "SELECT ba.C_BankAccount_ID,"                       //  1
                 + "b.Name || ' ' || ba.AccountNo AS Name, "          //  2
                   + "ba.C_Currency_ID, c.ISO_Code,"                   //  3..4
                   + "ba.CurrentBalance "                              //  5
                 + "FROM C_Bank b "
                 + "INNER JOIN C_BankAccount ba ON (b.C_Bank_ID=ba.C_Bank_ID) "
                 + "INNER JOIN C_Currency c ON (ba.C_Currency_ID=c.C_Currency_ID) "
                 + " AND ba.IsActive = 'Y'"
                 + " AND EXISTS (SELECT * FROM C_BankAccountDoc d WHERE d.C_BankAccount_ID=ba.C_BankAccount_ID) "
                 + " AND (ba.AD_Org_ID IN (SELECT ro.AD_Org_ID FROM AD_Role_OrgAccess ro"
                 + " where ba.c_bankaccount_id = " + Util.GetValueOfInt(cmbBankAccount.SelectedValue) + "))";

            DataSet dsBankAccount = null;

            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                dsBankAccount = DB.ExecuteDataset(sqlBankAccount, null, null);
                Dispatcher.BeginInvoke(delegate
                {
                    ISOCode = Util.GetValueOfString(dsBankAccount.Tables[0].Rows[0]["ISO_Code"]);
                    lblCurency.Content = ISOCode;

                    m_bankBalance = Util.GetValueOfDecimal(dsBankAccount.Tables[0].Rows[0]["CurrentBalance"]);

                    C_Currency_ID = Util.GetValueOfInt(dsBankAccount.Tables[0].Rows[0]["C_Currency_ID"]);

                    int C_BankAccount_ID = Util.GetValueOfInt(cmbBankAccount.SelectedValue);

                    string sqlPaymentRule = "select Name, Value from ad_ref_list where ad_reference_id = 195 "
                  + " AND AD_Ref_List.Value IN (SELECT PaymentRule FROM C_BankAccountDoc WHERE C_BankAccount_ID=" + C_BankAccount_ID + ") ORDER BY 2";

                    DataSet dsPaymentRule = null;
                    System.Threading.ThreadPool.QueueUserWorkItem(delegate
                    {
                        dsPaymentRule = DB.ExecuteDataset(sqlPaymentRule, null, null);

                        Dispatcher.BeginInvoke(delegate
                        {
                            cmbPaymentRule.ItemsSource = dsPaymentRule.Tables[0].GetBindableData(new Connector());
                            cmbPaymentRule.SelectedValuePath = "VALUE";
                            cmbPaymentRule.DisplayMemberPath = "NAME";
                            if (dsPaymentRule.Tables[0].Rows.Count > 0)
                            {
                                cmbPaymentRule.SelectedIndex = 0;
                            }
                            SetBusy(false);
                        });
                    });
                });
            });
        }

        /// <summary>
        /// Query and create TableInfo
        /// </summary>
        private void LoadTableInfo()
        {
            int countParam = 8;
            log.Config("");
            //  not yet initialized
            if (m_sql == null)
            {
                return;
            }

            String sql = m_sql;
            DateTime payDate = (DateTime)vdtpPayDate.SelectedDate;
            string paymentDate = payDate.ToString("dd-MMM-yyyy");
            int C_BankAccount_ID = Util.GetValueOfInt(cmbBankAccount.SelectedValue);
            log.Config("PayDate=" + payDate);
            String isSOTrx = "N";
            string paymentRule = Util.GetValueOfString(cmbPaymentRule.SelectedValue);
            if (paymentRule != "" && X_C_Order.PAYMENTRULE_DirectDebit.Equals(paymentRule))
            {
                isSOTrx = "Y";
                sql += " AND i.PaymentRule='" + X_C_Order.PAYMENTRULE_DirectDebit + "'";
            }
            if ((bool)chkDue.IsChecked)
            {
                sql += " AND i.DateInvoiced+p.NetDays <= @param9";
                countParam++;
            }
            int C_BPartner_ID = Util.GetValueOfInt(cmbBPartner.SelectedValue);
            if (C_BPartner_ID != 0)
            {
                sql += " AND i.C_BPartner_ID=@param10";
                countParam++;
            }
            sql += " ORDER BY 2,3";
            log.Finest(sql + " - C_Currecny_ID=" + C_Currency_ID + ", C_BPartner_ID=" + C_BPartner_ID);
            ////  Get Open Invoices
            SqlParameter[] para = null;
            try
            {
                para = new SqlParameter[countParam];
                int index = 0;
                para[index++] = new SqlParameter("@param1", paymentDate);
                para[index++] = new SqlParameter("@param2", C_Currency_ID);
                para[index++] = new SqlParameter("@param3", paymentDate);
                para[index++] = new SqlParameter("@param4", paymentDate);
                para[index++] = new SqlParameter("@param5", C_Currency_ID);
                para[index++] = new SqlParameter("@param6", paymentDate);
                para[index++] = new SqlParameter("@param7", isSOTrx);
                para[index++] = new SqlParameter("@param8", m_AD_Client_ID);

                if ((bool)chkDue.IsChecked)
                {
                    para[index++] = new SqlParameter("@param9", paymentDate);
                }
                if (C_BPartner_ID != 0)
                {
                    para[index++] = new SqlParameter("@param10", C_BPartner_ID);
                }

                System.Threading.ThreadPool.QueueUserWorkItem(delegate
                {
                    DataSet ds = DB.ExecuteDataset(sql, para, null);

                    Dispatcher.BeginInvoke(delegate
                    {
                        if (ds != null)
                        {
                            BindingSource source = new BindingSource(ds.Tables[0].GetBindableData(new Connector()));
                            vdgvPayment.ItemsSource = source;
                        }
                        btnGenerate.IsEnabled = false;
                        SetBusy(false);
                    });
                });

            }
            catch (Exception e)
            {
                log.Log(Level.SEVERE, sql, e);
            }
        }



        /// <summary>
        ///  Generate PaySelection
        /// </summary>
        private void GeneratePaySelect()
        {
            Decimal? paymentAmt = Util.GetValueOfDecimal(txtPaymentAmount.Text);
            log.Info("");
            Trx trx = null;
            Trx p_trx = null;

            List<int> Invoice_ID = new List<int>();
            List<Decimal?> openAmt = new List<Decimal?>();
            List<Decimal?> payAmt = new List<Decimal?>();

            int rowsSelected = 0;
            Decimal? totalAmt = 0;
            BindingSource rowSource = vdgvPayment.ItemsSource as BindingSource;
            for (int i = 0; i < rowSource.Count; i++)
            {
                if ((Convert.ToBoolean(((BindableObject)rowSource[i]).GetValue("SELECTROW"))))
                {
                    Decimal? amt = Util.GetValueOfDecimal(((BindableObject)rowSource[i]).GetValue("PAYMENTAMOUNT"));
                    Invoice_ID.Add(Util.GetValueOfInt(((BindableObject)rowSource[i]).GetValue("C_INVOICE_ID")));
                    openAmt.Add(Util.GetValueOfDecimal(((BindableObject)rowSource[i]).GetValue("AMOUNTDUE")));
                    payAmt.Add(Util.GetValueOfDecimal(((BindableObject)rowSource[i]).GetValue("PAYMENTAMOUNT")));
                    rowsSelected++;
                }
            }

            if (rowsSelected == 0)
            {
                return;
            }

            String paymentRule = Util.GetValueOfString(cmbPaymentRule.SelectedValue);
            int C_BankAccount_ID = Util.GetValueOfInt(cmbBankAccount.SelectedValue);
            ////  Create Header
            DateTime? payDate = Util.GetValueOfDateTime(vdtpPayDate.SelectedDate);

            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                MPaySelection m_ps = new MPaySelection(Envs.GetCtx(), 0, null);
                m_ps.SetName(Msg.GetMsg(Envs.GetCtx(), "VPaySelect")
                    + " - " + paymentRule
                    + " - " + payDate.Value.Date);
                m_ps.SetPayDate(payDate);
                m_ps.SetC_BankAccount_ID(C_BankAccount_ID);
                m_ps.SetIsApproved(true);
                if (!m_ps.Save())
                {
                    log.SaveError("SaveError", Msg.Translate(Envs.GetCtx(), "C_PaySelection_ID"));
                    m_ps = null;
                    return;
                }

                _C_PaySelection_ID = m_ps.GetC_PaySelection_ID();
                string name = m_ps.GetName();

                //string sqlTableID = "select ad_table_id from ad_table where tablename = 'C_PaySelection'";
                //int AD_Table_ID = Util.GetValueOfInt(DB.ExecuteScalar(sqlTableID, null, null));

                log.Config(m_ps.ToString());
                bool isSOTrx = false;
                if (X_C_Order.PAYMENTRULE_DirectDebit.Equals(paymentRule))
                {
                    isSOTrx = true;
                }

                int line = 0;
                Decimal? pAmt = Decimal.Zero;
                Decimal? oldpAmt = Decimal.Zero;
                for (int j = 0; j < Invoice_ID.Count; j++)
                {
                    line = line + 10;
                    if (Decimal.Add(pAmt.Value, Util.GetValueOfDecimal(payAmt[j])) > paymentAmt)
                    {
                        oldpAmt = Decimal.Subtract(paymentAmt.Value, pAmt.Value);
                    }
                    pAmt = Decimal.Add(pAmt.Value, Util.GetValueOfDecimal(payAmt[j]));
                    // pAmt = Util.GetValueOfDecimal(payAmt[j]);
                    MPaySelectionLine psl = new MPaySelectionLine(m_ps, line, paymentRule);
                    //psl.SetInvoice(Util.GetValueOfInt(Invoice_ID[j]), isSOTrx, Util.GetValueOfDecimal(openAmt[j]), Util.GetValueOfDecimal(payAmt[j]), Decimal.Subtract(Util.GetValueOfDecimal(openAmt[j]), Util.GetValueOfDecimal(payAmt[j])));
                    if (paymentAmt >= pAmt)
                    {
                        psl.SetInvoice(Util.GetValueOfInt(Invoice_ID[j]), isSOTrx, Util.GetValueOfDecimal(openAmt[j]), Util.GetValueOfDecimal(payAmt[j]), Decimal.Zero);
                        if (!psl.Save())
                        {
                            log.SaveError("PaymentSelectionLineNotSaved", "PaymentSelectionLineNotSaved");
                            return;
                        }
                        log.Fine("C_Invoice_ID=" + Util.GetValueOfInt(Invoice_ID[j]) + ", PayAmt=" + Util.GetValueOfDecimal(payAmt[j]));
                    }
                    else
                    {
                        psl.SetInvoice(Util.GetValueOfInt(Invoice_ID[j]), isSOTrx, Util.GetValueOfDecimal(openAmt[j]), oldpAmt.Value, Decimal.Zero);
                        if (!psl.Save())
                        {
                            log.SaveError("PaymentSelectionLineNotSaved", "PaymentSelectionLineNotSaved");
                            return;
                        }
                        log.Fine("C_Invoice_ID=" + Util.GetValueOfInt(Invoice_ID[j]) + ", PayAmt=" + Util.GetValueOfDecimal(payAmt[j]));
                    }

                }
                Dispatcher.BeginInvoke(delegate
                {
                    ShowMessage.AskMessage("Generate Payments from Payment Selection", true, name, "").Closed += (sc, ec) =>
                    {
                        if (false.Equals(((Message)sc).DialogResult))
                        {
                            Dispose();
                            return;
                        }
                        System.Threading.ThreadPool.QueueUserWorkItem(delegate
                        {

                            MPaySelection psel = new MPaySelection(Envs.GetCtx(), _C_PaySelection_ID, null);
                            if (psel.Get_ID() == 0)
                            {
                                throw new ArgumentException("Not found C_PaySelection_ID=" + _C_PaySelection_ID);
                            }
                            if (psel.IsProcessed())
                            {
                                throw new ArgumentException("@Processed@");
                            }
                            //
                            MPaySelectionLine[] lines = psel.GetLines(false);
                            List<MPaySelectionCheck> _list = new List<MPaySelectionCheck>();
                            for (int i = 0; i < lines.Length; i++)
                            {

                                MPaySelectionLine payLine = lines[i];
                                if (!payLine.IsActive() || payLine.IsProcessed())
                                {
                                    continue;
                                }
                                CreateCheck(payLine, _list);
                            }
                            //
                            psel.SetProcessed(true);
                            psel.Save();

                            string sql = "select ad_form_id from ad_form where classname = 'ViennaAdvantage.AForms.VPayPrint'";
                            int AD_Form_ID = Util.GetValueOfInt(DB.ExecuteScalar(sql, null, null));

                            //return "@C_PaySelectionCheck_ID@ - #" + _list.Count;
                            Dispatcher.BeginInvoke(delegate
                            {
                                SetBusy(false);
                                Dispose();
                                FormFrame ff = new FormFrame();
                                ff.OpenForm(AD_Form_ID);
                            });
                        });

                    };
                });

            });

        }   //  generatePaySelect

        /**
         *  Lock User Interface
         *  Called from the Worker before processing
         *  @param pi process Info
         */
        public void lockUI(VAdvantage.ProcessEngine.ProcessInfo pi)
        {
            //this.setEnabled(false);
            //m_isLocked = true;
        }   //  lockUI

        /**
         *  Unlock User Interface.
         *  Called from the Worker when processing is done
         *  @param pi process Info
         */
        public void unlockUI(VAdvantage.ProcessEngine.ProcessInfo pi)
        {
            ////	this.setEnabled(true);
            ////	m_isLocked = false;
            ////  Ask to Print it		//	Window is disposed
            //if (!ADialog.ask(0, this, "VPaySelectPrint?", "(" + pi.getSummary() + ")"))
            //    return;

            ////  Start PayPrint
            //int AD_Form_ID = 106;	//	Payment Print/Export
            //FormFrame ff = new FormFrame();
            //ff.openForm(AD_Form_ID);
            ////	Set Parameter
            //if (m_ps != null)
            //{
            //    VPayPrint pp = (VPayPrint)ff.getFormPanel();
            //    pp.setPaySelection(m_ps.getC_PaySelection_ID());
            //}
            ////
            //ff.pack();
            //this.setVisible(false);
            //AEnv.showCenterScreen(ff);
            //this.dispose();
        }   //  unlockUI

        /**
         *  Is the UI locked (Internal method)
         *  @return true, if UI is locked
         */
        public bool isUILocked()
        {
            return m_isLocked;
        }   //  isLoacked

        /**
         *  Method to be executed async.
         *  Called from the ASyncProcess worker
         *  @param pi process Info
         */
        public void executeASync(VAdvantage.ProcessEngine.ProcessInfo pi)
        {
            log.Config("-");
        }

        private void CreateCheck(MPaySelectionLine line, List<MPaySelectionCheck> _list)
        {

            string _PaymentRule = "S";
            if (_PaymentRule != null && _PaymentRule.Equals(X_C_Order.PAYMENTRULE_DirectDebit))
                _PaymentRule = null;
            ////	Try to find one
            for (int i = 0; i < _list.Count; i++)
            {
                MPaySelectionCheck check = (MPaySelectionCheck)_list[i];
                //	Add to existing
                if (check.GetC_BPartner_ID() == line.GetInvoice().GetC_BPartner_ID())
                {
                    check.AddLine(line);
                    if (!check.Save())
                    {
                        throw new Exception("Cannot save MPaySelectionCheck");
                    }
                    line.SetC_PaySelectionCheck_ID(check.GetC_PaySelectionCheck_ID());
                    line.SetProcessed(true);
                    if (!line.Save())
                    {
                        throw new Exception("Cannot save MPaySelectionLine");
                    }
                    return;
                }
            }
            ////	Create new
            String PaymentRule = line.GetPaymentRule();
            if (_PaymentRule != null && _PaymentRule != " ")
            {
                if (!X_C_Order.PAYMENTRULE_DirectDebit.Equals(PaymentRule))
                {
                    PaymentRule = _PaymentRule;
                }
            }
            MPaySelectionCheck check1 = new MPaySelectionCheck(line, PaymentRule);
            if (!check1.IsValid())
            {
                int C_BPartner_ID = check1.GetC_BPartner_ID();
                MBPartner bp = MBPartner.Get(Envs.GetCtx(), C_BPartner_ID);
                String msg = "@NotFound@ @C_BP_BankAccount@: " + bp.GetName();
                throw new Exception(msg);//CompiereUserException(msg);
            }
            if (!check1.Save())
            {
                throw new Exception("Cannot save MPaySelectionCheck");
            }
            line.SetC_PaySelectionCheck_ID(check1.GetC_PaySelectionCheck_ID());
            line.SetProcessed(true);
            if (!line.Save())
            {
                throw new Exception("Cannot save MPaySelectionLine");
            }
            _list.Add(check1);
        }


        #region EventRegion

        private void cmbBankAccount_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (bAcc)
            {
                SetBusy(true);
                LoadBankInfo();
            }
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            Dispose();
        }

        private void btnGenerate_Click(object sender, RoutedEventArgs e)
        {
            SetBusy(true);
            GeneratePaySelect();

        }

        private void btnRefresh_Click(object sender, RoutedEventArgs e)
        {
            if (cmbBPartner.SelectedIndex == -1)
            {
                ShowMessage.Info("SelectBusinessPartnerFirst", true, null, null);
                return;
            }
            LoadTableInfo();
            vDataStatus.Content = "0 " + Msg.GetMsg(Envs.GetCtx(), "Selected") + " - 0.00, " + Msg.GetMsg(Envs.GetCtx(), "Remaining") + " 0.00";
        }


        private void cmbBPartner_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SetBusy(true);
            LoadTableInfo();
            vDataStatus.Content = "0 " + Msg.GetMsg(Envs.GetCtx(), "Selected") + " - 0.00, " + Msg.GetMsg(Envs.GetCtx(), "Remaining") + " 0.00";
        }

        private void vdgvPayment_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // if (e.getColumn() == 0)
            //        calculateSelection();
        }

        private void vdgvPayment_CellEditEnded(object sender, DataGridCellEditEndedEventArgs e)
        {

        }

        private void SetBusy(bool value)
        {
            this.IsEnabled = !value;
            busyWindow.Visibility = value ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
            // txtBusy.Visibility = value ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
        }

        private void busyWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
        }

        #endregion

    }

 
}
